package main

import (
	"context"
	"fmt"
	"github.com/panjf2000/ants"
	"github.com/rs/xid"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"math/rand"
	"strconv"
	"time"
)

type Person struct {
	Name  string
	Phone string
}

type MessageBody struct {
	Uid        string `bson: "Uid"`
	Touid      string `bson: "Touid"`
	UserType   string `bson: "UserType"`
	ClientType string `bson: "ClientType"`
	ChatType   string `bson: "ChatType"`

	OrderNumber string `bson: "OrderNumber"`
	Status      string `bson: "Status"`
	ChatTime    string `bson: "ChatTime"`
	Msgid       string `bson: "Msgid"`
	NickName    string `bson: "NickName"`

	IconUrl    string `bson: "IconUrl"`
	Content    string `bson: "Content"`
	CreateTime string `bson: "CreateTime"`
	RemoveFlag string `bson: "RemoveFlag"`
}

type MessageBody1 struct {
	Uid        uint32 `bson: "Uid"`
	Touid      uint32 `bson: "Touid"`
	UserType   uint32 `bson: "UserType"`
	ClientType uint32 `bson: "ClientType"`
	ChatType   uint32 `bson: "ChatType"`

	OrderNumber string `bson: "OrderNumber"`
	Status      int    `bson: "Status"`
	ChatTime    uint64 `bson: "ChatTime"`
	Msgid       string `bson: "Msgid"`
	NickName    string `bson: "NickName"`

	IconUrl    string `bson: "IconUrl"`
	Content    string `bson: "Content"`
	RemoveFlag uint32 `bson: "RemoveFlag"`
}

func GetNewInstanceID() (string, error) {
	guid := xid.New()
	return guid.String(), nil
}

func main() {
	var (
		client *mongo.Client
		err    error
	)

	clientOptions := options.Client().ApplyURI("mongodb://192.168.16.117:27017/")
	if client, err = mongo.Connect(context.TODO(), clientOptions); err != nil {
		fmt.Println("连接mongodb失败：", err)
		return
	}

	// 检查连接
	err = client.Ping(context.TODO(), nil)
	if err != nil {
		fmt.Println(" MongoDB ping err: ", err)
	}
	fmt.Println("Connected to MongoDB!")

	defer func() {
		err = client.Disconnect(context.TODO())
		if err != nil {
			fmt.Println("断开连接失败：", err)
		}
	}()

	// 插入一条数据
	// InsertTestData(client)
	// 测试
	TestData(client)

}

// 新增数据
func InsertTestData(client *mongo.Client) {
	database := client.Database("db_test")
	collection := database.Collection("tb_test")

	var (
		results *mongo.InsertOneResult
		err     error
	)

	peple := new(Person)
	peple.Name = "test"
	peple.Phone = "12346546"
	if results, err = collection.InsertOne(context.TODO(), peple); err != nil {
		fmt.Println(err)
		return
	}
	fmt.Println(results)
	//// _id: 默认生成一个全局唯一ID, ObjectID：12字节的二进制
	fmt.Println(results.InsertedID)

}

// 查询一条数据
func SearchTestData(client *mongo.Client) {
	database := client.Database("db_test")
	collection := database.Collection("test_doc")
	data := new(Person)
	err := collection.FindOne(context.TODO(), bson.D{{"jobName", "job02"}}).Decode(data)
	if err != nil {
		fmt.Println("查询错误：", err)
	} else {
		fmt.Println("查询成功：", data)
	}

}

func MakeTestData(client *mongo.Client) {
	i := 0
	for {
		i++
		if i > 400000 {
			time.Sleep(time.Second)
			break
		}
		time.Sleep(time.Microsecond)
		rand.Seed(time.Now().UnixNano())
		num := rand.Intn(9500)
		data, err := SearchTestOneData(client, int64(num))
		if err != nil {
			fmt.Println("获取数据失败", err)
			return
		}
		data2 := make([]interface{}, 0)
		// 1577808000 - 1609430399 = 31,622,399
		for i := range data {
			data1 := new(MessageBody1)
			data1.Content = data[i].Content
			data1.IconUrl = data[i].IconUrl
			data1.Msgid, _ = GetNewInstanceID()
			data1.OrderNumber = data[i].OrderNumber
			toId, _ := strconv.ParseInt(data[i].Touid, 10, 64)
			data1.Touid = uint32(toId)
			data1.ChatTime = uint64(rand.Intn(31622399)) + 1577808000
			chatType, _ := strconv.ParseInt(data[i].ChatType, 10, 64)
			data1.ChatType = uint32(chatType)
			removeFlag, _ := strconv.ParseInt(data[i].RemoveFlag, 10, 64)
			data1.RemoveFlag = uint32(removeFlag)
			clientType, _ := strconv.ParseInt(data[i].ClientType, 10, 64)
			data1.Status = 0
			data1.ClientType = uint32(clientType)
			userType, _ := strconv.ParseInt(data[i].UserType, 10, 64)
			data1.UserType = uint32(userType)
			uid, _ := strconv.ParseInt(data[i].Uid, 10, 64)
			data1.Uid = uint32(uid)
			// InsertTestOneData(client, data1)
			data2 = append(data2, data1)
		}

		ants.Submit(func() {
			InsertManyData(client, data2)
		})

	}

}

func InsertManyData(client *mongo.Client, messages []interface{}) {
	database := client.Database("db_test")
	collection := database.Collection("tb_test")
	var (
		// results *mongo.InsertManyResult
		err error
	)
	if _, err = collection.InsertMany(context.TODO(), messages); err != nil {
		fmt.Println(err)
		return
	}
	//// _id: 默认生成一个全局唯一ID, ObjectID：12字节的二进制
}

// 查询多条数据
func SearchTestOneData(client *mongo.Client, skip int64) ([]*MessageBody, error) {
	database := client.Database("db_test")
	collection := database.Collection("tb_source")
	data := make([]*MessageBody, 0)
	var (
		limit int64 = 100
	)
	cursor, err := collection.Find(context.Background(),
		bson.D{}, &options.FindOptions{Skip: &skip, Limit: &limit})
	if err != nil {
		fmt.Println("查询错误：", err)
		return nil, err
	}
	err = cursor.All(context.TODO(), &data)
	if err != nil {
		return nil, err
	}
	return data, nil
}

// 插入一条数据
func InsertTestOneData(client *mongo.Client, data *MessageBody1) {
	database := client.Database("db_test")
	collection := database.Collection("tb_test")

	var (
		//results *mongo.InsertOneResult
		err error
	)

	if _, err = collection.InsertOne(context.TODO(), data); err != nil {
		fmt.Println(err)
		return
	}
	//fmt.Println(results)
	//// _id: 默认生成一个全局唯一ID, ObjectID：12字节的二进制
	//fmt.Println(results.InsertedID)

}

// 根据mdgID查询一条数据
func SearchOneDataByMsgId(client *mongo.Client, msgId string) {
	database := client.Database("db_test")
	collection := database.Collection("tb_test")
	data := new(MessageBody1)
	err := collection.FindOne(context.TODO(), bson.D{{"msgid", msgId}}).Decode(data)
	if err != nil {
		fmt.Println("查询错误：", err)
	} else {
		fmt.Println("查询成功：", data)
	}
	fmt.Println("获取数据结果为：", data)

}

// 分页查询某个订单的聊天记录
func SearchDataSkip(client *mongo.Client, orderNumber string, page, num int64) {
	database := client.Database("db_test")
	collection := database.Collection("tb_test")
	data := make([]*MessageBody1, 0)
	cursor, err := collection.Find(context.Background(),
		bson.D{{"ordernumber", orderNumber}},
		&options.FindOptions{Skip: &page, Limit: &num, Sort: "chattime"})
	if err != nil {
		fmt.Println("查询错误：", err)
		return
	}
	err = cursor.All(context.TODO(), &data)
	if err != nil {
		return
	}

}

// 查询某个msgid之前的数量
func SearchCountOneCur(client *mongo.Client, orderNumber, msgId string) {
	database := client.Database("db_test")
	collection := database.Collection("tb_test")
	data := make([]*MessageBody1, 0)
	cursor, err := collection.Find(context.Background(),
		bson.D{{"ordernumber", orderNumber},
			{"msgId", bson.D{{"$gt", msgId}}}},
		// &options.FindOptions{Skip: &page, Limit: &num, Sort: "chattime"}
	)
	if err != nil {
		fmt.Println("查询错误：", err)
		return
	}
	err = cursor.All(context.TODO(), &data)
	if err != nil {
		return
	}

}

func TestData(client *mongo.Client) {
	startTime := time.Now().Unix()
	// 生产数据
	MakeTestData(client)

	// 按照id查询一条数据
	// SearchOneDataByMsgId(client, "bv965u3vhdv17u3rjhv0")

	// 分页查询用户聊天记录

	// 某个msgid之前的数据量
	//c.Find(bson.M{"touid": uid, "ordernumber": orderNumber, "status": 0, "msgid": bson.M{"$gt": msgid}}).Sort(ssort).Count()
	//SearchCountOneCur(client, "200831235741WCOJOB", "bv965u3vhdv17u3rjhv0")

	//获取聊天消息最新n条

	//获取聊天某条消息的前或后n条
	//c.Find(bson.M{"ordernumber": orderNum, "msgid": bson.M{sopt: msgid}}).Sort(ssort).Limit(cnt).All(&dataArr)

	// 删除某条数据

	endTime := time.Now().Unix()
	fmt.Println("消耗的时间为：", endTime-startTime)
}
